package com.seari.ats;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.GenericFutureListener;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.seari.ats.handler.AtsDecoder;
import com.seari.ats.handler.AtsEncoder;
import com.seari.ats.handler.AtsHandler;
import com.seari.ats.handler.AtsSenderRunnable;
import com.seari.bean.BaseClient;
import com.seari.commonutils.redis.JedisUtilProxy;
import com.seari.utils.DataUtil;

public class AtsClient extends BaseClient {

	protected static Logger logger = LoggerFactory.getLogger(AtsClient.class);
	

	public AtsClient(String host, int port) {
		this.host = host;
		this.port = port;
	}

	public AtsClient() {
	}

	@Override
	public void setup() throws Exception {

		// workerGroup处理已经被接收的连接
		NioEventLoopGroup workerGroup = new NioEventLoopGroup();
		AtsClient client = this;
		// workerGroup.scheduleAtFixedRate(command, initialDelay, period, unit);

		try {
			// Bootstrap是一个启动 NIO 服务的辅助启动类
			Bootstrap b = new Bootstrap();
			b.group(workerGroup);
			// 使用NioSocketChannel类的新的channel接收进来的连接
			b.channel(NioSocketChannel.class);
			// option() 是提供给NioSocketChannel用来接收进来的连接
			b.option(ChannelOption.SO_KEEPALIVE, true);

			// 处理最近接收的channel
			b.handler(new ChannelInitializer<SocketChannel>() {
				@Override
				public void initChannel(SocketChannel ch) throws Exception {
					// 设定IdleStateHandler心跳检测每五秒进行一次写检测，如果五秒内write()方法未被调用则触发一次userEventTrigger()方法，实现客户端每五秒秒向服务端发送一次消息
					ch.pipeline().addLast(
							new IdleStateHandler(0, 5, 0, TimeUnit.SECONDS));
					// 解码器
					ch.pipeline().addLast("AtsDecoder", new AtsDecoder());
					// 处理器
					ch.pipeline().addLast("AtsHanler", new AtsHandler(client));
					// 编码器
					ch.pipeline().addLast("AtsEncoder", new AtsEncoder());

				}
			});
			// Start the client. 绑定端口然后启动服务
			ChannelFuture f = b.connect(host, port).sync();

			channel = f.channel();
			System.out.println(channel);

			// 实例化 利用channel 调用线程池中线程
			// new AtsSender(channel).CiosSendData();

			// Wait until the connection is closed.
			if (f.isSuccess()) {
				logger.info("连接成功");
				// 初始化连接池
				JedisUtilProxy.initJedisPoolUtil("127.0.0.1", 6379);
				AtsSenderRunnable atsSenderRunnable = new AtsSenderRunnable(channel);
				Thread t = new Thread(atsSenderRunnable);
				t.start();
				t.run();

			}
			

			
			// f.channel().closeFuture().sync();
			f.channel().closeFuture()
					.addListener(new GenericFutureListener<ChannelFuture>() {
						@Override
						public void operationComplete(ChannelFuture f)
								throws Exception {
							workerGroup.shutdownGracefully();
						}
					});
		} catch (Exception ex) {
			logger.warn(ex.getMessage());
		}

	}

	@Override
	public void reset() throws Exception {

		if (null != channel) {
			AtsHandler handler = (AtsHandler) channel.pipeline().get(
					"AtsHandler");
			if (null != handler) {
				// handler.closeJedis();
			}
			channel.close();
		}
		setup();

	}

	/**
	 * 发送请求计划列车运行信息
	 */
	public void sendPlanTrain() {

		ByteBuf byteBuf = null;
		byteBuf = channel.alloc().buffer(6 * 4);
		// SystemID
		byteBuf.writeByte(0xff);
		// Total Length
		byteBuf.writeByte(0x00);
		byteBuf.writeByte(0x05);
		// Multi-flag
		byteBuf.writeByte(0x00);
		// 消息长度
		byteBuf.writeByte(0x00);
		byteBuf.writeByte(0x02);
		// byteBuf.writeByte(0x0002);
		// msg_id
		byteBuf.writeByte(0x20);
		byteBuf.writeByte(0x02);
		// byteBuf.writeByte(0x2002);

		logger.info(
				"send ATS PlanTrain {}",
				DataUtil.BytesToHexStr(new byte[] { (byte) 0xff, 0x0005, 0x000,
						0x0002, (byte) 0x2002 }));

		channel.writeAndFlush(byteBuf);
	}

	/**
	 * 发送请求实际列车运行信息
	 */
	public void sendPracticTrain() {
		ByteBuf byteBuf = null;
		byteBuf = channel.alloc().buffer(6 * 4);
		// SystemID
		byteBuf.writeByte(0xff);
		// Total Length
		byteBuf.writeByte(0x00);
		byteBuf.writeByte(0x05);
		// Multi-flag
		byteBuf.writeByte(0x00);
		// 消息长度
		byteBuf.writeByte(0x00);
		byteBuf.writeByte(0x02);
		// msg_id
		byteBuf.writeByte(0x20);
		byteBuf.writeByte(0x03);

		logger.info("send ATS PracticTrain {}");

		/*
		 * DataUtil.BytesToHexStr(new byte[] { (byte) 0xff, 0x0005, 0x000,
		 * 0x0002, (byte) 0x2003 })
		 */

		channel.writeAndFlush(byteBuf);

	}

	/**
	 * 测试使用
	 * 
	 * @param args
	 */
	public static void main(String args[]) {
		AtsClient ats = new AtsClient("127.0.0.1", 4001);
		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					ats.setup();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}).start();
		;
	}
}
